#ifndef __BUZZER_H__
#define __BUZZER_H__

/* TIM counter clock = SystemCoreClock / (Prescaler+1) */
#define DEFAULT_PRESCALER                   4
#define BPR_TIMER                           TIM12
#define RCC_BPR_TIMER                       RCC_APB1Periph_TIM12
#define RCC_BPR_PWM_PORT                    RCC_AHB1Periph_GPIOB
#define BPR_PWM_PORT                        GPIOB
#define BPR_PWM_PIN                         GPIO_Pin_15
#define BPR_TIM_PIN_SOURCE                  GPIO_PinSource15

#define MAX_FREQUENCY_VALUE         0xFFFF
#define MAX_VOLUME_VALUE            0xFFFF
#define ERROR_FREQ_HZ               420
#define LOW_FREQ_HZ                 1500
#define MEDIUM_FREQ_HZ              2400
#define HIGH_FREQ_HZ                2840
#define LOW_DUTY                    6
#define MEDIUM_DUTY                 12
#define HIGH_DUTY                   50

/* Unit = Hz */
const unsigned short FrequencyTable[] = {
    ERROR_FREQ_HZ,
    LOW_FREQ_HZ,
    MEDIUM_FREQ_HZ,
    HIGH_FREQ_HZ
};

/* Unit = % Current Frequency */
const unsigned short VolumeTable[] = {
    LOW_DUTY,
    MEDIUM_DUTY,
    HIGH_DUTY
};

enum freq_t {
    FREQUENCY_ERROR  = 0,
    FREQUENCY_LOW    = 1,
    FREQUENCY_MEDIUM = 2,
    FREQUENCY_HIGH   = 3
};

enum volume_t {
    VOLUME_LOW      = 0,
    VOLUME_MEDIUM   = 1,
    VOLUME_HIGH     = 2
};

#ifdef __cplusplus
extern "C" {
#endif

extern void buzzer_open(void);
extern void buzzer_close(void);
extern void buzzer_on(void);
extern void buzzer_off(void);
extern void buzzer_config(enum freq_t freq, enum volume_t vol);

#ifdef __cplusplus
}
#endif

#endif /* __BUZZER_H__ */